<?php

namespace app\admin\controller\shop;

use app\admin\library\Auth;
use app\common\controller\Backend;
use Exception;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
use app\admin\model\shop\GoodsAttr;
use app\admin\model\shop\Spec;
use app\admin\model\shop\GoodsSkuSpec;
use function fast\e;

/**
 * 商品管理
 *
 * @icon fa fa-circle-o
 */
class Goods extends Backend
{

    /**
     * 快速搜索时执行查找的字段
     */
    protected $searchFields = 'id,goods_sn,title,subtitle';

    /**
     * Goods模型对象
     * @var \app\admin\model\shop\Goods
     */
    protected $model = null;
    protected $sku_model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\shop\Goods;
        $this->sku_model = new \app\admin\model\shop\GoodsSku;

        $this->view->assign("flagList", $this->model->getFlagList());
        $this->view->assign("statusList", $this->model->getStatusList());
    }

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(['Freight', 'Brand', 'Category'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }


    /**
     * 查看
     */
    public function select()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(['Freight', 'Brand', 'Category'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    //检查属性skus 和 spec 是否对上
    protected function checkSku($skus, $spec)
    {
        foreach ($skus as $item) {
            if (!isset($item['skus']) || !is_array($item['skus']) || empty($item['skus'])) {
                throw new Exception('规格属性不能为空');
            }
            if (!isset($item['price']) || !isset($item['marketprice'])) {
                throw new Exception('请录入价格');
            }
            if (($item['marketprice'] > 0 || $item['price'] > 0 || $item['stocks'] > 0) && $item['marketprice'] <= $item['price']) {
                throw new Exception('市场价必须大于销售价');
            }
            foreach ($item['skus'] as $k => $v) {
                if (empty($v) && !is_numeric($v)) {
                    throw new Exception('规格【' . $v . '】属性值不能为空');
                }
                if (!isset($spec[$k]['value']) || (empty($spec[$k]['name']) && !is_numeric($spec[$k]['name']))) {
                    throw new Exception('规格【' . $v . '】名称不能为空');
                }
                foreach ($spec[$k]['value'] as $m => $n) {
                    if (stripos($n, ',') !== false) {
                        throw new Exception('规格【' . $v . '】属性值中不能包含,');
                    }
                }
                if (count($spec[$k]['value']) != count(array_unique($spec[$k]['value']))) {
                    throw new Exception('规格【' . $v . '】属性值中不能有重复值');
                }
                if (empty($spec[$k]['value']) || !in_array($v, $spec[$k]['value'])) {
                    throw new Exception('规格【' . $v . '】属性不匹配');
                }
            }
        }
    }

    protected function getSkuId($skus, $newSpec, $spec)
    {
        $arr = [];
        foreach ($skus as $index => $item) {
            $specArr = $spec[$index];
            foreach ($newSpec as $subindex => $subitem) {
                if ($subitem['spec_name'] == $specArr['name'] && $subitem['spec_value_value'] == $item) {
                    $arr[] = $subitem['id'];
                }
            }
        }
        sort($arr);
        return implode(',', $arr);
    }

    //添加商品属性
    protected function addGoodsSku($skus, $spec, $goods_id)
    {
        //属性入库
        $specList = Spec::push($spec);
        $newSpec = GoodsSkuSpec::push($specList, $goods_id);
        //匹配属性
        $list = $this->sku_model->where('goods_id', $goods_id)->select();
        $newData = [];
        $stocks = 0;
        foreach ($skus as $k => $sk) {
            $newSkuId = $this->getSkuId($sk['skus'], $newSpec, $spec);
            $newSkuData = [
                'goods_id'    => $goods_id,
                'sku_id'      => $newSkuId,
                'goods_sn'    => $sk['goods_sn'] ?? '',
                'image'       => $sk['image'] ?? '',
                'price'       => $sk['price'] ?? 0,
                'marketprice' => $sk['marketprice'] ?? 0,
                'stocks'      => $sk['stocks'] ?? 0,
            ];
            if (isset($list[$k])) {
                $row = $list[$k];
                $oldSkuIdsArr = explode(',', $row['sku_id']);
                sort($oldSkuIdsArr);
                $oldSkuId = implode(',', $oldSkuIdsArr);

                if ($oldSkuId == $newSkuId) {
                    //相等的更新
                    $row->save($newSkuData);
                } else {
                    //不等的
                    $row->save(array_merge($newSkuData, ['sales' => 0]));
                }
                unset($list[$k]);
            } else { //多余的
                $newData[] = array_merge($newSkuData, ['sales' => 0]);
            }
            $stocks = bcadd($stocks, $sk['stocks'] ?? 0);
        }
        if (!empty($newData)) {
            $this->sku_model->saveAll($newData);
        }
        //更新库存
        if (!empty($skus)) {
            $this->model->where('id', $goods_id)->update(['stocks' => $stocks, 'spectype' => 1]);
        } else {
            $this->model->where('id', $goods_id)->update(['spectype' => 0]);
        }
        //原来多的删除
        foreach ($list as $it) {
            $it->delete();
        }
    }

    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                        $this->model->validateFailException(true)->validate($validate);
                    }
                    $result = $this->model->allowField(true)->save($params);
                    //商品规格
                    if (isset($params['skus']) && isset($params['spec'])) {
                        $params['skus'] = (array)json_decode($params['skus'], true);
                        $params['spec'] = (array)json_decode($params['spec'], true);
                        $this->checkSku($params['skus'], $params['spec']);
                        $this->addGoodsSku($params['skus'], $params['spec'], $this->model->id);
                    }
                    //商品属性
                    if (isset($params['attribute_ids'])) {
                        GoodsAttr::addGoodsAttr($params['attribute_ids'], $this->model->id);
                    }
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);
                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }
                    $result = $row->allowField(true)->save($params);
                    //商品规格
                    if (isset($params['skus']) && isset($params['spec'])) {
                        $params['skus'] = (array)json_decode($params['skus'], true);
                        $params['spec'] = (array)json_decode($params['spec'], true);
                        $this->checkSku($params['skus'], $params['spec']);
                        $this->addGoodsSku($params['skus'], $params['spec'], $row->id);
                    }
                    //商品属性
                    if (isset($params['attribute_ids'])) {
                        GoodsAttr::addGoodsAttr($params['attribute_ids'], $row->id);
                    }
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        //查询属性输出
        $list = $this->sku_model->field("sku.*,GROUP_CONCAT(sp.name,':',sv.value ORDER BY sp.id asc) sku_attr")
            ->alias('sku')
            ->where('sku.goods_id', $row->id)
            ->join('shop_goods_sku_spec p', "FIND_IN_SET(p.id,sku.sku_id)", 'LEFT')
            ->join('shop_spec sp', 'sp.id=p.spec_id', 'LEFT')
            ->join('shop_spec_value sv', 'sv.id=p.spec_value_id', 'LEFT')
            ->group('sku.id')
            ->select();
        $this->view->assign("row", $row);
        $this->assignconfig('goods', $row);
        $this->assignconfig('goods_skus', $list);
        return $this->view->fetch();
    }

    public function import()
    {
        $file = $this->request->request('file');
        if (!$file) {
            $this->error(__('Parameter %s can not be empty', 'file'));
        }

        $filePath = ROOT_PATH . 'public' . DS . $file;
        if (!is_file($filePath)) {
            $this->error(__('No results were found'));
        }

        $spreadsheet = IOFactory::load($filePath);
        $worksheet = $spreadsheet->getActiveSheet();
        $rows = $worksheet->toArray();
        $orderSnAndSpecNameMap = [];
        $currentGoods = null;
        $totalRows = count($rows);
        // 从第2行开始遍历
        for ($i = 1; $i < $totalRows; $i++) {
            $row = $rows[$i];
            if (empty(array_filter($row))) {
                continue;
            }
            // 新商品（$row[0]有值）
            if (!empty($row[0])) {
                if ($currentGoods!== null) {
                    $this->processGoods($currentGoods); // 处理上一个商品，无中断响应
                }
                $orderSn = $row[6];
                $category = Db::name('shop_category')->where('name', $row[2])->value('id');
                if (empty($category)) {
                    $this->error("存在不存在的分类，请核实后重试");
                }
                $currentGoods = [
                    'params' => [
                        'category_id' => $category,
                        'title' => $row[5],
                        'brand' => NULL,
                        'goods_sn' => $row[8],
                        'marketprice' => $row[9],
                        'price' => $row[10],
                        'stocks' => $row[11],
                        'weight' => $row[12],
                        'gtin' => $row[13],
                        'description' => $row[14],
                        'content' => $row[15],
                        'images' => $row[4],
                        'image' => $row[3],
                    ],
                    'order_sn' => $orderSn,
                    'goods_sn' => $row[8],
                    'spec_names' => [
                        $row[16], $row[17], $row[18], $row[19],
                    ],
                    'spec_items' => [],
                ];
                $orderSnAndSpecNameMap[$orderSn] = [
                    'specName1' => $row[16],
                    'specName2' => $row[17],
                    'specName3' => $row[18],
                    'specName4' => $row[19],
                ];
            }
            // 商品规格项（$row[0]为空）
            else if ($currentGoods !== null) {
                // 处理规格图片（$row[19]为规格图列）


                $validSpecs = [];
                $orderSn = $currentGoods['order_sn'];

                // 规格1
                if (!empty($row[16]) && !empty($orderSnAndSpecNameMap[$orderSn]['specName1'])) {
                    $specName = $orderSnAndSpecNameMap[$orderSn]['specName1'];
                    $specId = Db::name('shop_spec')->where('name', $specName)->value('id');
                    $specValueId = Db::name('shop_spec_value')
                        ->where('spec_id', $specId)
                        ->where('value', $row[16])
                        ->value('id');
                    if ($specId && $specValueId) {
                        $validSpecs[] = [
                            'name' => $specName,
                            'spec_id' => $specId,
                            'value' => $row[16],
                            'value_id' => $specValueId,
                        ];
                    }
                }
                // 规格2
                if (!empty($row[17]) && !empty($orderSnAndSpecNameMap[$orderSn]['specName2'])) {
                    $specName = $orderSnAndSpecNameMap[$orderSn]['specName2'];
                    $specId = Db::name('shop_spec')->where('name', $specName)->value('id');
                    $specValueId = Db::name('shop_spec_value')
                        ->where('spec_id', $specId)
                        ->where('value', $row[17])
                        ->value('id');
                    if ($specId && $specValueId) {
                        $validSpecs[] = [
                            'name' => $specName,
                            'spec_id' => $specId,
                            'value' => $row[17],
                            'value_id' => $specValueId,
                        ];
                    }
                }
                // 规格3
                if (!empty($row[18]) && !empty($orderSnAndSpecNameMap[$orderSn]['specName3'])) {
                    $specName = $orderSnAndSpecNameMap[$orderSn]['specName3'];
                    $specId = Db::name('shop_spec')->where('name', $specName)->value('id');
                    $specValueId = Db::name('shop_spec_value')
                        ->where('spec_id', $specId)
                        ->where('value', $row[18])
                        ->value('id');
                    if ($specId && $specValueId) {
                        $validSpecs[] = [
                            'name' => $specName,
                            'spec_id' => $specId,
                            'value' => $row[18],
                            'value_id' => $specValueId,
                        ];
                    }
                }
                // 规格4
                if (!empty($row[19]) && !empty($orderSnAndSpecNameMap[$orderSn]['specName4'])) {
                    $specName = $orderSnAndSpecNameMap[$orderSn]['specName4'];
                    $specId = Db::name('shop_spec')->where('name', $specName)->value('id');
                    $specValueId = Db::name('shop_spec_value')
                        ->where('spec_id', $specId)
                        ->where('value', $row[19])
                        ->value('id');
                    if ($specId && $specValueId) {
                        $validSpecs[] = [
                            'name' => $specName,
                            'spec_id' => $specId,
                            'value' => $row[19],
                            'value_id' => $specValueId,
                        ];
                    }
                }

                if (!empty($validSpecs)) {
                    $currentGoods['spec_items'][] = [
                        'valid_specs' => $validSpecs,
                        'goods_sn' => $row[8],
                        'price' => $row[10],
                        'marketprice' => $row[9],
                        'stocks' => $row[11],
                        'image' => '',
                    ];
                }
            }
        }

        // 处理最后一个商品
        if ($currentGoods !== null) {
            $this->processGoods($currentGoods);
        }

        // 所有商品处理完成后，统一返回成功响应
        $this->success(__('Import successful'));
    }

// 商品处理方法：每次使用新模型实例
    private function processGoods(&$goods)
    {
        Db::startTrans();
        try {
            // 1. 实例化新模型（必须用实例操作，禁止静态调用）
            $newModel = new $this->model();
            $params = $goods['params'];
            $specItems = $goods['spec_items'];
            $skus = [];
            $specGroups = [];

            // 2. 组装规格组和SKU（修正：SKU存value_id，确保关联有效）
            foreach ($specItems as $item) {
                $validSpecs = $item['valid_specs'];
                // 组装规格组
                foreach ($validSpecs as $vs) {
                    $specKey = $vs['name'];
                    if (!isset($specGroups[$specKey])) {
                        $specGroups[$specKey] = [
                            'name' => $vs['name'],
                            'value' => [],
                        ];
                    }
                    if (!in_array($vs['value'], $specGroups[$specKey]['value'])) {
                        $specGroups[$specKey]['value'][] = $vs['value'];
                    }
                }
                var_dump($specGroups);
                // 组装SKU：必须存 value_id（之前存value导致规格关联失败）
                $skuAttr = [];
                $skuValues = [];
                foreach ($validSpecs as $vs) {
                    $skuAttr[] = "{$vs['name']}:{$vs['value']}";
                    $skuValues[] = $vs['value']; // 关键修复：存规格值ID，不是文字值
                }
                $skus[] = [
                    'skus' => $skuValues,
                    'goods_sn' => $item['goods_sn'],
                    'price' => $item['price'],
                    'marketprice' => $item['marketprice'],
                    'stocks' => $item['stocks'],
                    'is_del' => false,
                    'sku_attr' => implode(',', $skuAttr),
                    'image' => $item['image'],
                ];
            }

            // 3. 组装规格和SKU字段（不删除，直接同步到商品表）
            $spec = array_values($specGroups);

            // 移除无用参数（brand字段为空，无需传递）
            unset($params['brand']);

            // 4. 新增/更新商品（用模型实例操作，禁止静态调用）
            $exists = $this->model->where(['goods_sn' => $goods['goods_sn'], 'deletetime'=> NULL])->find();
            if ($exists) {
                $params['updatetime'] = time();
                // 更新：用实例的where+update，确保条件精准
                $result = $this->model->where(['goods_sn' => $goods['goods_sn'], 'deletetime'=> NULL])->update($params);
                $goodsId = $exists['id']; // 直接用查询到的ID，无需再次查询
            } else {
                $params['updatetime'] = time();
                $params['createtime'] = time();
                // 新增：用实例的save方法，自动赋值ID
                $result = $this->model->insertGetId($params);
                $goodsId = $result; // 实例直接获取新增ID
            }
            if (!empty($skus) && !empty($spec)) {
                $params['skus'] = json_encode($skus);
                $params['spec'] = json_encode($spec);
            }
            // 5. 校验保存结果
            if (!$result) {
                $msg = $exists ? "更新失败" : "新增失败";
                throw new Exception("商品【{$params['title']}】{$msg}");
            }

            // 6. 处理SKU（删除旧SKU，新增新SKU）
            $this->sku_model->where('goods_id', $goodsId)->delete();
            if (isset($params['skus']) && isset($params['spec'])) {
                $params['skus'] = (array)json_decode($params['skus'], true);
                $params['spec'] = (array)json_decode($params['spec'], true);
                $this->checkSku($params['skus'], $params['spec']);
                $this->addGoodsSku($params['skus'], $params['spec'], $goodsId);
            }

            // 7. 商品属性（若有）
            if (isset($params['attribute_ids'])) {
                GoodsAttr::addGoodsAttr($params['attribute_ids'], $goodsId);
            }

            $goods = []; // 清空当前商品数据，避免影响下一个
            Db::commit();
        } catch (ValidateException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

}
